using System;
using System.Collections.Generic;
using System.Text;
using SubSonic;
using StructureMap;

using Impact.Infrastructure;
using Impact.Infrastructure.Exceptions;
using Impact.Model.Objects;
using Impact.Model.Service;
using Impact.Views;

namespace Impact.Controllers
{
    /// <summary>
    /// controller for editing pages in the admin
    /// </summary>
    public class EditPageController
    {
        private IPageService service;
        private IPageEditorView view;
        private Guid userId;

        /// <summary>
        /// default constructor
        /// </summary>
        /// <param name="view">the view this controller is using</param>
        /// <param name="userId">user ID of administrator using this functionality</param>
        public EditPageController( IPageEditorView view, Guid userId )
        {
            this.view = view;
            this.userId = userId;
            this.service = ObjectFactory.GetInstance<IPageService>();
        }

        /// <summary>
        /// perform startup functionality for the controller
        /// </summary>
        /// <param name="isFirstTime">true if this is the first time this controller is loaded,
        /// false if this is a postback</param>
        public void Initialize( bool isFirstTime )
        {

            if ( isFirstTime )
            {
                ImpactPage page = null;
                if ( CurrentPageId != null )
                {
                    // if pageId is valid, we're editing.
                    page = service.FetchByID( CurrentPageId.Value );
                }
                else
                {
                    // otherwise, we're adding.
                    page = new ImpactPage();
                }
                view.PopulateForm( page );

            }

        }

        /// <summary>
        /// Retrieve all pages (includes disabled) that are available to be parent pages to the current page
        /// </summary>
        public ImpactPageCollection GetAvailableParents()
        {
            ImpactPageCollection output = new ImpactPageCollection();
            if ( CurrentPageId != null )
            {
                ImpactPageCollection all = service.FetchAllPages( false );
                foreach ( ImpactPage page in all )
                {
                    if ( !page.PageId.Equals( CurrentPageId ) && page.ParentPageId == -1 )
                    {
                        output.Add( page );
                    }
                }
            }
            return output;
        }

        /// <summary>
        /// retrieve all pages that are templates
        /// </summary>
        /// <returns></returns>
        public TemplateCollection GetTemplates()
        {
            return service.FetchAllTemplates();
        }

        /// <summary>
        /// commit the data from the view to the data store
        /// </summary>
        public void SavePage()
        {
            ImpactPage page = view.RetrieveFormData();
            service.Save( page, userId );
        }

        /// <summary>
        /// gets the pageId of the page currently being edited.
        /// </summary>
        protected int? CurrentPageId
        {
            get
            {
                string pageIdParam = view.Parameters["pid"];
                int pageId = -1;
                int? output = null;
                if ( Int32.TryParse( pageIdParam, out pageId ) )
                {
                    output = pageId;
                }
                return output;
            }
        }

        /// <summary>
        /// Retrieve a page based on the ID
        /// </summary>
        public ImpactPage GetPage( int pageId )
        {
            IPageService pageService = ObjectFactory.GetInstance<IPageService>();
            return pageService.FetchByID( pageId );
        }

        /// <summary>
        /// Retrieve a profile based on the page passed in
        /// </summary>
        public Profile GetProfileFromPage( ImpactPage page )
        {
            Profile p = GetProfile( page.PageId );
            if ( !Profile.IsValid( p ) )
            {
                p = new Profile();
            }
            return p;
        }

        /// <summary>
        /// Retrieve the given profile
        /// </summary>
        public Profile GetProfile( int pageId )
        {
            IProfileService profileService = ObjectFactory.GetInstance<IProfileService>();
            return profileService.FetchProfile( pageId );
        }
    }
}
